package logger

import (
	"go.uber.org/atomic"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"os"
)

var Log *WailsZapLoggerAdaptor

var sugar *zap.SugaredLogger
var logger *zap.Logger
var level = &atomic.String{}

func init() {
	SetLevel(zapcore.DebugLevel)
	encoder := zapcore.NewConsoleEncoder(DefaultEncoderConfig())
	multiWriteSyncer := zapcore.NewMultiWriteSyncer(DefaultConsoleSyncer())

	core := zapcore.NewCore(encoder, multiWriteSyncer, DefaultLevelEnabler())
	logger = zap.New(core, zap.AddCaller())
	defer func() {
		_ = logger.Sync()
	}()
	sugar = logger.Sugar()

	Log = &WailsZapLoggerAdaptor{logger: sugar}
}

func DefaultTimeEncoder() (timeEncoder zapcore.TimeEncoder) {
	timeEncoder = zapcore.RFC3339TimeEncoder
	return
}

func SetLevel(l zapcore.Level) {
	level.Store(l.String())
}

func DefaultLevelEnabler() zap.LevelEnablerFunc {
	return func(z zapcore.Level) bool {
		atomicLevel := zap.NewAtomicLevel()
		_ = atomicLevel.UnmarshalText([]byte(level.Load()))
		return z >= atomicLevel.Level()
	}
}

func DefaultEncoderConfig() (encoderConfig zapcore.EncoderConfig) {
	encoderConfig = zap.NewProductionEncoderConfig()
	encoderConfig.EncodeTime = DefaultTimeEncoder()
	encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
	return
}

func DefaultConsoleSyncer() zapcore.WriteSyncer {
	return zapcore.AddSync(os.Stdout)
}
